<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Vue监测数据改变的原理——数组</title>
        <!-- 引入Vue -->
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <div id="root">
            <!-- 
                数据劫持

                Vue监视数据的原理：
                1. vue会监视data中所有层次的数据。

                2. 如何监测对象中的数据？
                    通过setter实现监视，且要在new vue时就传入要监测的数据。
                    （1）对象中后追加的属性，Vue默认不做响应式处理
                    （2）如需给后添加的属性做响应式，请使用如下API：
                        Vue.set(target, propertyName/index, value) 或
                        vm.$set(target, propertyName/index, value)
                
                3. 如何监测数组中的数据？
                    通过包装数组更新元素的方法实现，本质就是做了两件事：
                    （1）调用原生对应的方法对数组进行更新
                    （2）重新解析模板，进而更新页面。

                4. 在Vue修改数组中的某个元素一定要用如下方法：
                    （1）使用这些API： push()、pop()、shift()、unshift()、splice()、sort()、reverse()
                    （2）Vue.set()或vm.$set()

                特别注意：Vue.set()和vm.$set()不能给vm或vm的根数据对象（也就是data）添加属性！！！

                无论是数据劫持还是数据代理，都离不开Object.propertyDefine
             -->


            <h2>学生信息</h2>
            <button @click="student.age++">年龄+1岁</button> <br><br>
            <button @click="addSex">添加性别属性，默认值：男</button><br><br>
            <button @click="student.sex='未知'">修改性别为：未知</button><br><br>
            <button @click="addFriend">在列表首位添加一个朋友</button><br><br>
            <button @click="updateFriend">修改第一个朋友的名字为：王五</button><br><br>
            <button @click="addHobby">添加一个爱好</button><br><br>
            <button @click="updateHobby">修改第一个爱好为：开车</button><br><br>

            <h2>姓名：{{student.name}}</h2>
            <!-- 如果有性别，就展示，没有性别就不展示 -->
            <h2 v-if="student.sex">性别：{{student.sex}}</h2>
            <h2>年龄：{{student.age}}</h2>
            <h2>朋友：</h2>
            <ul>
                <li v-for="(f, index) in student.friends" :key="index">
                    {{f.name}}--{{f.sex}}
                </li>
            </ul>

            <h2>爱好：</h2>
            <ul>
                <li v-for="(h, index) in student.hobbys" :key="index">
                    {{h}}
                </li>
            </ul>
        </div>
        <script type="text/javascript">
            Vue.config.productionTip = false    // 阻止Vue在启动时生成生产提示

            // 使用计算属性实现列表过滤
            const vm = new Vue({
                el: '#root',
                data: {
                    student: {
                        name: 'tom',
                        age: 18,
                        friends: [
                            {name: '张三', sex: '男'},
                            {name: '小花', sex: '女'}
                        ],
                        hobbys:['唱歌', '跳舞', '打篮球']
                    }
                },
                methods: {
                    addSex(){
                        // Vue.set(this.student, 'sex', '男')
                        this.$set(this.student, 'sex', '男')
                    },
                    addFriend() {
                        this.student.friends.unshift({name: '李四', sex: "男"})
                    },
                    updateFriend(){
                        this.student.friends[0].name = '王五'
                    },
                    addHobby(){
                        this.student.hobbys.push('学习')
                    },
                    updateHobby(){
                        // this.student.hobbys.splice(0, 1, '开车')
                        Vue.set(this.student.hobbys, 0, '开车')
                        // this.$set(this.student.hobbys, 0, '开车')
                    }
                },
            })
        </script>
    </body>
</html>
